﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using ValidationFramework.Reflection;
using ValidationFramework.Specifications.Tests.Helpers;
using ValidationFramework.Specifications;

namespace ValidationFramework.Specifications.Tests
{
    [TestFixture]
    public class IsInRangeRuleAttributeTests
    {

        [Test]
        public void Should_Be_Able_To_Infer_Type_From_Descriptor1()
        {
            // Arrange
            var attribute = new IsInRangeAttribute(1, 3);
            var descriptor = new FakeReflectionInfo(TypePointers.IntTypeHandle);

            // Act
            var validator = attribute.CreateSpecification(descriptor);

            // Assert
			Assert.IsInstanceOfType(typeof(IsInRangeSpec<int>), validator);
        }
        [Test]
        public void Should_Be_Able_To_Infer_Type_From_Descriptor2()
        {
            // Arrange
            var attribute = new IsInRangeAttribute("a", "z");
            var descriptor = new FakeReflectionInfo(TypePointers.StringTypeHandle);

            // Act
            var validator = attribute.CreateSpecification(descriptor);

            // Assert
			Assert.IsInstanceOfType(typeof(IsInRangeSpec<string>), validator);
        }
        [Test]
        public void Should_Be_Able_To_Infer_Type_From_Descriptor3()
        {
            // Arrange
			var attribute = new IsInRangeAttribute(DateTime.Now, DateTime.Now.AddHours(1));
            var descriptor = new FakeReflectionInfo(TypePointers.DateTimeTypeHandle);

            // Act
            var validator = attribute.CreateSpecification(descriptor);

            // Assert
			Assert.IsInstanceOfType(typeof(IsInRangeSpec<DateTime>), validator);
        }

        public void Should_Pass_Spec_Properties_Through()
        {
            // Arrange
			var attribute = new IsInRangeAttribute(DateTime.Now, DateTime.Now.AddHours(1))
                {
                    EqualsMaximumIsValid = true,
                    EqualsMinimumIsValid = false
                };
            var descriptor = new FakeReflectionInfo(TypePointers.DateTimeTypeHandle);

            // Act
            var validator = attribute.CreateSpecification(descriptor);

            // Assert
			Assert.IsInstanceOfType(typeof(IsInRangeSpec<DateTime>), validator);
			var rangeSpec = (IsInRangeSpec<DateTime>)validator;
            Assert.IsTrue(rangeSpec.EqualsMaximumIsValid);
            Assert.IsFalse(rangeSpec.EqualsMinimumIsValid);
        }

		public void Should_Accept_Doubles_As_Params()
		{
			// Arrange
			var expectedLow = 0.1;
			var expectedHigh = 99.99;
			var attribute = new IsInRangeAttribute(expectedLow, expectedHigh);
			var descriptor = new FakeReflectionInfo(TypePointers.DoubleTypeHandle);

			// Act
			var validator = attribute.CreateSpecification(descriptor);

			// Assert
			Assert.IsInstanceOfType(typeof(IsInRangeSpec<Double>), validator);
			var rangeSpec = (IsInRangeSpec<Double>)validator;
			Assert.AreEqual(expectedLow, rangeSpec.Minimum);
			Assert.AreEqual(expectedHigh, rangeSpec.Maximum);
		}
    }
}
